//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   UniformSource.hh
 * \author Jeremy Roberts
 * \date   Sep 1, 2011
 * \brief  UniformSource class definition.
 * \note   Copyright (C) 2011 Jeremy Roberts. 
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author::                                            $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//


#ifndef UNIFORMSOURCE_HH_
#define UNIFORMSOURCE_HH_

#include <iostream>
#include <vector>

#include "source/BaseSource.hh"
#include "angle/AngleTraits.hh"
#include "angle/Octant.hh"
#include "../utilities/SP.hh"

namespace slabtran
{

//===========================================================================//
/*!
 * \class UniformSource
 * \brief Derived BaseSource defining a geometrically uniform external source.
 *
 * In some cases (likely testing), being able to define a single source
 * for the entire mesh may be useful.  The client can set a single isotropic
 * volumetric source strength for all groups, or a strength for each group.
 *
 * \tparam  D   Dimension.
 *
 * \todo Make a test for me.
 *
 */
//===========================================================================//

template <class D>
class UniformSource : public BaseSource<D>
{

public:

  //\{
  //! Useful typedefs for classes that use UniformSource
  typedef util::SP<UniformSource<D> >       SP_source;
  typedef typename Octant<D>::Omega         Omega;
  //\}

  /*
   *  \brief Constructor, single strength.
   *
   *  This creates a UniformSource with the same strength in all groups.
   *
   *  \param    number_groups   Number of groups.
   *  \param    strength        Isotropic source strength in units /cm^3.
   */
  UniformSource(int number_groups, double strength) :
    BaseSource<D> (),
    d_number_groups(number_groups),
    d_source(number_groups, strength * Norm<D>::norm)
  {
    //
  }

  /*
   *  \brief Constructor, vector of strengths.
   *
   *  This creates a UniformSource with each group strength
   *  defined separately.
   *
   *  \param    number_groups   Number of groups.
   *  \param    strengths       Isotropic source strengths in units /cm^3.
   */
  UniformSource(int number_groups, std::vector<double> strengths) :
    BaseSource<D>(),
    d_number_groups(number_groups),
    d_source(strengths)
  {
    Require(strengths.size() == d_number_groups);
    // Normalize for correct angular units.
    for (int g = 0; g < d_number_groups; g++)
      d_source[g] *= Norm<D>::norm;
  }

  // >>> DERIVED INTERFACE

  /// Return the number of groups.
  int number_groups() const
  {
    return d_number_groups;
  }

  /*
   *  \brief Get source in particles/cm^3-ster.
   *
   *  \param    cell    Spatial cell of source.
   *  \param    angle   Angle.
   *  \param    g       Group of requested source.
   *  \return           Source for requested cell, angle, and direction.
   *
   */
  double q_e(int cell, const Omega &angle, int g) const
  {
    Require(g >= 0 && g < d_number_groups);
    return d_source[g];
  }

  /// Verify that all of the sources have been assigned.
  bool verify() const
  {
    return (d_source.size() > 0);
  }

private:

  // >>> DATA

  /// Number of groups.
  const int d_number_groups;

  /// Uniform group source.
  std::vector<double> d_source;

};

} // end namespace slabtran

#endif /* UNIFORMSOURCE_HH_ */

//---------------------------------------------------------------------------//
//              end of UniformSource.hh
//---------------------------------------------------------------------------//
